﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
using SqlSugarCoreDemo.DBSqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace SqlSugarCoreDemo.Controllers
{
    [ApiController]
    [Route("login")]
    public class LoginController : ControllerBase
    {
        private readonly ILogger<LoginController> _logger;
        /// <summary>
        /// SqlSugar数据库对象
        /// </summary>
        private readonly SqlSugarScope _dbBase;

        /// <summary>
        /// 数据库基础对象
        /// </summary>
        private ISqlSugarClient DbBaseClient => _dbBase;

        public LoginController(ILogger<LoginController> logger, IUnitOfWork unitOfWork)
        {
            _logger = logger;
            _dbBase = unitOfWork.GetDbClient();
        }

        [AllowAnonymous]
        [HttpGet]
        [HttpPost]
        public async Task Login()
        {
            string message = string.Empty;
            //通过管理员名获取实体类 
            SysManager manager = new SysManager() { id = 199, managerRoleIds = "1,2", password = "207D2EF40251" };

            //读取Tolen
            SysManagerToken managerToken = await DbBaseClient.Queryable<SysManagerToken>().FirstAsync(t => t.managerId == manager.id);

            //插入登录日志（注：如果第二次访问这个API，这个插入就会报错，数据库连接失败。但是如果删除下面的三表联查的代码就会没问题。。。。）
             int logId = await DbBaseClient.Insertable(new SysManagerLog
            {
                appsId = 0,
                managerId = (manager != null ? manager.id : 0),
                userName = "userName",
                actionType = 1,
            }).ExecuteReturnIdentityAsync();

            //三表联查(注：如果删除这个查询请求，无论多少次请求都正常)
            List<SysManagerRoleMenuSelect> listSelect = await QueryMuchAsync<SysManagerRoleMenu, SysMenuRoute, SysRoute, SysManagerRoleMenuSelect>(
                (mrm, mr, r) => new object[]
                {
                    JoinType.Left, mrm.menuRouteId == mr.id,
                    JoinType.Left, mr.routeId == r.id
                },
                (mrm, mr, r) => new SysManagerRoleMenuSelect
                {
                    managerRoleMenu = mrm,
                    menuRoute = mr,
                    route = r
                },
                (mrm, mr, r) => r.apiUrl != "" && r.apiUrl != null
            );

            //返回
            message = "操作成功！";
            Console.WriteLine("\r\n" + message);
            return;
        }

        /// <summary>
        /// 查询-三表查询
        /// </summary>
        /// <typeparam name="T">实体1</typeparam>
        /// <typeparam name="SysMenuRoute">实体2</typeparam>
        /// <typeparam name="SysRoute">实体3</typeparam>
        /// <typeparam name="SysManagerRoleMenuSelect">返回对象</typeparam>
        /// <param name="joinExpression">关联表达式 (join1,join2) => new object[] {JoinType.Left,join1.UserNo==join2.UserNo}</param>
        /// <param name="selectExpression">返回表达式 (s1, s2) => new { Id =s1.UserNo, Id1 = s2.UserNo}</param>
        /// <param name="whereLambda">查询表达式 (w1, w2) =>w1.UserNo == "")</param>
        /// <param name="blUseNoLock">使用WITH(NOLOCK)脏读</param>
        /// <returns>值</returns>
        public async Task<List<SysManagerRoleMenuSelect>> QueryMuchAsync<SysManagerRoleMenu, SysMenuRoute, SysRoute, SysManagerRoleMenuSelect>(
            Expression<Func<SysManagerRoleMenu, SysMenuRoute, SysRoute, object[]>> joinExpression,
            Expression<Func<SysManagerRoleMenu, SysMenuRoute, SysRoute, SysManagerRoleMenuSelect>> selectExpression,
            Expression<Func<SysManagerRoleMenu, SysMenuRoute, SysRoute, bool>> whereLambda = null,
            bool blUseNoLock = false)
        {
            return blUseNoLock
                ? await DbBaseClient.Queryable(joinExpression).Where(whereLambda).Select(selectExpression)
                    .With(SqlWith.NoLock)
                    .ToListAsync()
                : await DbBaseClient.Queryable(joinExpression).Where(whereLambda).Select(selectExpression)
                    .ToListAsync();
        }
    }
}
